package com.thinkit.bigdata.core.util.es;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.thinkit.bigdata.core.util.DateFormatUtil;
import com.thinkit.bigdata.web.controller.pubmet.PubMethod;
import com.thinkit.bigdata.web.coremet.SystemStatic;
import com.thinkit.bigdata.web.dao.bus.BusModelRuleMapper;
import com.thinkit.bigdata.web.dao.sys.SysConfigMapper;
import com.thinkit.bigdata.web.model.BaseEntity;
import com.thinkit.bigdata.web.model.bus.BusModelRule;
import com.thinkit.bigdata.web.model.bus.BusModelRuleExample;
import com.thinkit.bigdata.web.model.bus.BusWork;
import com.thinkit.bigdata.web.model.bus.BusWorkWithBLOBs;
import com.thinkit.bigdata.web.model.es.audioEs.*;
import com.thinkit.bigdata.web.model.es.countEs.CountSource;
import com.thinkit.bigdata.web.model.perCenter.PendingTaskModel;
import com.thinkit.bigdata.web.model.result.Constants;
import com.thinkit.bigdata.web.model.result.HtmlResult;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.DateConverter;
import org.apache.log4j.Logger;
import org.apache.lucene.search.join.ScoreMode;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.NestedQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.rest.RestStatus;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.InvocationTargetException;
import java.net.UnknownHostException;
import java.util.*;

/**
 * Created by BanAiQin on 2017/5/10.
 * es相关方法
 */
@Service
public class ESUtil {

    private static Logger logger = Logger.getLogger(ESUtil.class);

    @Resource
    private SysConfigMapper configMapper;

    @Resource
    private BusModelRuleMapper busModelRuleMapper;

    public List<Source> strs2Entitys(List<String> docList) {
        List<Source> sources = new ArrayList<>();
        for (String doc : docList) {
            sources.add(str2entity(doc));
        }
        return sources;
    }

    public List<CountSource> strs2Entitys1(List<String> docList) {
        List<CountSource> sources = new ArrayList<>();
        for (String doc : docList) {
            sources.add(str2entity1(doc));
        }
        return sources;
    }

    public Source str2entity(String doc) {
        return JSON.parseObject(doc, Source.class);
    }

    public CountSource str2entity1(String doc) {
        return JSON.parseObject(doc, CountSource.class);
    }

    public List<PendingTaskModel> formatModel(List<String> docList, String workId) {
        List<PendingTaskModel> taskModels = new ArrayList<>();
        for (Source source : strs2Entitys(docList)) {
            Integer proStatus = null;
            String proUserName = null;
            Integer workScore = null;
            Integer proFlag = null;
            String workName = null;
            String updateTime = null;
            Integer preQuality = null;
            for (WorkScores workScores : source.getWorkScores()) {
                if (workId.equals(workScores.getWorkId().toString())) {
                    proStatus = workScores.getProStatus();
                    proUserName = workScores.getProUserName();
                    proFlag = workScores.getProFlag();
                    workName = workScores.getWorkName();
                    workScore = workScores.getWorkScore();
                    updateTime = workScores.getUpdateTime();
                    preQuality = workScores.getPreQuality();
                    break;
                }
            }
            PendingTaskModel taskModel = new PendingTaskModel(
                    source.getVoiceInfo().getProvinceCode(),
                    source.getVoiceInfo().getProvince(),
                    workId,
                    workName,
                    source.getSerialNumber(),
                    source.getVoiceInfo().getCustomerNum(),
                    source.getVoiceInfo().getProPhoneNum(),
                    source.getVoiceInfo().getSeatGroup(),
                    source.getVoiceInfo().getSeatId(),
                    source.getVoiceInfo().getSeatName(),
                    source.getVoiceInfo().getIsEachRecord(),
                    source.getVoiceInfo().getHoldDuration(),
                    source.getVoiceInfo().getCallStartTime(),
                    source.getVoiceInfo().getCallEndTime(),
                    proStatus,
                    proFlag,
                    proUserName,
                    workScore,
                    source.getVoiceInfo().getInputTime(),
                    updateTime,
                    preQuality,
                    source.getVoiceInfo().getCallDirection(),
                    source.getVoiceInfo().getOnHook(),
                    source.getVoiceInfo().getReCallFlag(),
                    source.getVoiceInfo().getSatisfaction(),
                    source.getVoiceInfo().getCustomerloc(),
                    source.getVoiceInfo().getCustomerLevel(),
                    source.getVoiceInfo().getCustomerSign()
            );
            taskModels.add(taskModel);
        }
        return taskModels;
    }

    public List<PendingTaskModel> formatModelSerialNumber(List<String> docList) {
        List<PendingTaskModel> taskModels = new ArrayList<>();
        for (Source source : strs2Entitys(docList)) {
            PendingTaskModel taskModel = new PendingTaskModel();
            taskModel.setSerialNumber(source.getSerialNumber());
            taskModels.add(taskModel);
        }
        return taskModels;
    }

    public List<VoiceInfoDto> formatModel(List<String> docList) throws InvocationTargetException, IllegalAccessException {
        List<VoiceInfoDto> voiceInfos = new ArrayList<>();
        for (Source source : strs2Entitys(docList)) {
            VoiceInfoDto dto = new VoiceInfoDto();
            ConvertUtils.register(new DateConverter(null), java.util.Date.class);
            BeanUtils.copyProperties(dto, source.getVoiceInfo());
            dto.setSerialNumber(source.getSerialNumber());
            if (source.getCallTags() != null) {
                dto.setCallTags(source.getCallTags());
            }
            voiceInfos.add(dto);
        }
        return voiceInfos;
    }

    public List<String> formatIds(List<String> docList) {
        List<String> ids = new ArrayList<>();
        for (Source source : strs2Entitys(docList)) {
            ids.add(source.getSerialNumber());
        }
        return ids;
    }

    public Source getSourceBySerialNumber(String serialNumber) {
        String mgs = SystemStatic.crud.get(SystemStatic.AUDIO_ES_INDEX, SystemStatic.AUDIO_ES_TYPE, serialNumber);
        return this.str2entity(mgs);
    }

    public HtmlResult updateSource(Source source) {
        RestStatus status = SystemStatic.crud.updateIndexRefreshByNow(SystemStatic.AUDIO_ES_INDEX, SystemStatic.AUDIO_ES_TYPE, JSON.toJSONString(source), source.getSerialNumber());
        if (200 == status.getStatus()) {
            return HtmlResult.success("数据操作成功");
        }
        logger.info("数据更新失败,状态码为【" + status.getStatus() + "】");
        return HtmlResult.failure("数据更新失败");
    }

    public HtmlResult updateSources(List<Source> sources) {
        boolean bool = true;
        for (Source source : sources) {
            RestStatus status = SystemStatic.crud.updateIndexRefreshByNow(SystemStatic.AUDIO_ES_INDEX, SystemStatic.AUDIO_ES_TYPE, JSON.toJSONString(source), source.getSerialNumber());
            if (200 != status.getStatus()) {
                bool = false;
                break;
            }
        }
        if (bool) {
            return HtmlResult.success("数据操作成功");
        }
        return HtmlResult.failure("数据更新失败");
    }

    /**
     * 数据权限方法
     * @param boolQuery -
     * @param seatId -
     */
    public void formatQ(BoolQueryBuilder boolQuery, String seatId) {
        Session session = SecurityUtils.getSubject().getSession();
        //数据权限
        if (!Strings.isNullOrEmpty(seatId)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.seatId", seatId));
        } else {
            int userIdentity = (Integer) session.getAttribute("userIdentity");
            if (BaseEntity.USERIDENTITY_ZJ == userIdentity) {//质检
                List<Long> groupIds = (List<Long>) session.getAttribute("groupIds");
                if (groupIds != null) {
                    BoolQueryBuilder shouldBoolQuery = QueryBuilders.boolQuery();
                    for (Long groupId : groupIds) {
                        shouldBoolQuery.should(QueryBuilders.matchQuery("voiceInfo.groupId", groupId));
                    }
                    boolQuery.must(shouldBoolQuery);
                } else { //质检员没有任何管理的坐席组，查不到任何数据
                    boolQuery.must(QueryBuilders.matchQuery("voiceInfo.groupId", "-99999"));
                }
            } else {
                List<String> userIds = (List<String>) session.getAttribute("userIds");
                if (userIds != null) {
                    BoolQueryBuilder shouldBoolQuery = QueryBuilders.boolQuery();
                    for (String userId : userIds) {
                        shouldBoolQuery.should(QueryBuilders.matchQuery("voiceInfo.seatId", userId));
                    }
                    boolQuery.must(shouldBoolQuery);
                }
            }

        }
    }

    /**
     * 坐席登陆任务搜索条件的数据权限
     * @param workList -
     * @param works -
     * @return -
     * @throws UnknownHostException -
     */
    public List<BusWorkWithBLOBs> taskListQ(List<BusWorkWithBLOBs> workList, List<BusWorkWithBLOBs> works) throws UnknownHostException {
        for (BusWorkWithBLOBs work : works) {
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            //数据权限
            this.formatQ(boolQuery, "");
            boolQuery.must(
                    QueryBuilders.nestedQuery(
                            "workScores",
                            QueryBuilders.matchQuery("workScores.workId", work.getId()),
                            ScoreMode.None
                    )
            );
            int count = SystemStatic.crud.queryQBuilderAllByMes(SystemStatic.AUDIO_ES_INDEX, SystemStatic.AUDIO_ES_TYPE, boolQuery);
            if (count == 0) {
                continue;
            }
            workList.add(work);
        }
        return workList;
    }

    /**
     * 数据权限方法,用于我的考核
     * @param boolQuery -
     * @param seatId -
     */
    public void formatQResult(BoolQueryBuilder boolQuery, String seatId) {
        Session session = SecurityUtils.getSubject().getSession();
        //数据权限
        if (!Strings.isNullOrEmpty(seatId)) {
            boolQuery.must(QueryBuilders.matchQuery("seatId", seatId));
        } else {
            int userIdentity = (Integer) session.getAttribute("userIdentity");
            if (BaseEntity.USERIDENTITY_ZJ == userIdentity) {//质检
                List<Long> groupIds = (List<Long>) session.getAttribute("groupIds");
                if (groupIds != null) {
                    BoolQueryBuilder shouldBoolQuery = QueryBuilders.boolQuery();
                    for (Long groupId : groupIds) {
                        shouldBoolQuery.should(QueryBuilders.matchQuery("groupId", groupId));
                    }
                    boolQuery.must(shouldBoolQuery);
                } else { //质检员没有任何管理的坐席组，查不到任何数据
                    boolQuery.must(QueryBuilders.matchQuery("groupId", "-99999"));
                }
            } else {
                List<String> userIds = (List<String>) session.getAttribute("userIds");
                if (userIds != null) {
                    BoolQueryBuilder shouldBoolQuery = QueryBuilders.boolQuery();
                    for (String userId : userIds) {
                        boolQuery.must(shouldBoolQuery.should(QueryBuilders.matchQuery("seatId", userId)));
                    }
                }
            }
        }
    }

    private void taskStatusForm(List<Integer> workStatus, String proStatus) {
        int userIdentity = (Integer) SecurityUtils.getSubject().getSession().getAttribute("userIdentity");
        //坐席  已质检 和 复检完成
        if (BaseEntity.USERIDENTITY_ZX == userIdentity) {
            if (!Strings.isNullOrEmpty(proStatus)) {
                if (Integer.parseInt(proStatus) != BaseEntity.SM_WORK_PROSTATUS_APPEAL_RUN) {
                    workStatus.add(Integer.parseInt(proStatus));
                } else {
                    workStatus.add(9999);
                }
            } else {
                workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0);
                workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30);

            }
        } else if (BaseEntity.USERIDENTITY_ZJ == userIdentity) {//质检员  已申诉
            if (!Strings.isNullOrEmpty(proStatus)) {
                if (Integer.parseInt(proStatus) != BaseEntity.SM_WORK_PROSTATUS_APPEAL_YES && Integer.parseInt(proStatus) != BaseEntity.SM_WORK_PROSTATUS_APPEAL_NO) {
                    workStatus.add(Integer.parseInt(proStatus));
                } else {
                    workStatus.add(9999);
                }
            } else {
                workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20);
            }
        } else {//集团人员
            if (!Strings.isNullOrEmpty(proStatus)) {
                workStatus.add(Integer.parseInt(proStatus));
            } else {
                workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_NULL);
                workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0);
                workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20);
                workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30);
            }
        }
    }

    /**
     * 待办任务 提示标记
     * @param boolQuery -
     */
    public void taskTitleQ(BoolQueryBuilder boolQuery, String workId) {
        List<Integer> workStatus = new ArrayList<>();
        workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0);
        workStatus.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30);
        BoolQueryBuilder workStatusShouldQ = QueryBuilders.boolQuery();
        for (Integer status : workStatus) {
            workStatusShouldQ.should(QueryBuilders.matchQuery("workScores.proStatus", status));
        }
        BoolQueryBuilder builder = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("workScores.workId", workId))
                .must(workStatusShouldQ)
                .must( QueryBuilders.nestedQuery(
                        "workScores.modelRules",
                        QueryBuilders.existsQuery("workScores.modelRules.ruleId"),
                        ScoreMode.None
                ));
        NestedQueryBuilder nestedQ = QueryBuilders.nestedQuery(
                "workScores",
                builder,
                ScoreMode.None
        );
        boolQuery.must(nestedQ);
    }

    /**
     * 待办任务 数据查询条件
     * @param boolQuery -
     */
    public void taskFormatQ(BoolQueryBuilder boolQuery, String proStatus, String workId, String proFlag) {
        List<Integer> workStatus = new ArrayList<>();
        this.taskStatusForm(workStatus, proStatus);
        BoolQueryBuilder builder = QueryBuilders.boolQuery();
        builder.must(QueryBuilders.matchQuery("workScores.workId", workId));
        if (!workStatus.isEmpty()) {
            BoolQueryBuilder workStatusShouldQ = QueryBuilders.boolQuery();
            for (Integer status : workStatus) {
                workStatusShouldQ.should(QueryBuilders.matchQuery("workScores.proStatus", status));
            }
            builder.must(workStatusShouldQ);
        }
        builder.must(QueryBuilders.nestedQuery(
                "workScores.modelRules",
                QueryBuilders.existsQuery("workScores.modelRules.ruleId"),
                ScoreMode.None
        ));
        if (!Strings.isNullOrEmpty(proFlag)) {
            builder.must(QueryBuilders.matchQuery("workScores.proFlag", proFlag));
        }
        NestedQueryBuilder nestedQ = QueryBuilders.nestedQuery(
                "workScores",
                builder,
                ScoreMode.None
        );
        boolQuery.must(nestedQ);
    }

    /**
     * 待办任务 随录信息
     * @param boolQuery -
     * @param request -
     * @param logTxt -
     */
    public void taskFormVoice(BoolQueryBuilder boolQuery, HttpServletRequest request, String logTxt) {
        String provinceCode = request.getParameter("provinceCode");//省份
        String groupId = request.getParameter("groupId");//坐席班组
        String seatId = request.getParameter("seatId");//坐席姓名
        String customerNumber = request.getParameter("customerNumber");//客户号码
        String callStartTime = request.getParameter("callStartTime");//通话开始时间
        String callEndTime = request.getParameter("callEndTime");//通话结束时间
        String serialNumber = request.getParameter("serialNumber");//录音流水
        logger.info(logTxt + "groupId = " + groupId);
        logger.info(logTxt + "seatId = " + seatId);
        logger.info(logTxt + "customerNumber = " + customerNumber);
        logger.info(logTxt + "callStartTime = " + callStartTime);
        logger.info(logTxt + "callEndTime = " + callEndTime);
        logger.info(logTxt + "serialNumber = " + serialNumber);
        if (!Strings.isNullOrEmpty(serialNumber)) {
            boolQuery.must(QueryBuilders.wildcardQuery("serialNumber", "*" + serialNumber + "*"));
        }
        if (!Strings.isNullOrEmpty(provinceCode)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.provinceCode", provinceCode));
        }
        if (!Strings.isNullOrEmpty(seatId)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.seatId", seatId));
        }
        if (!Strings.isNullOrEmpty(customerNumber)) {
            boolQuery.must(QueryBuilders.wildcardQuery("voiceInfo.customerNum", "*" + customerNumber + "*"));
        }
        if (!Strings.isNullOrEmpty(groupId)) {
            boolQuery.must(QueryBuilders.matchQuery("voiceInfo.groupId", groupId));
        }
        if (!Strings.isNullOrEmpty(callStartTime)) {
            PubMethod.formatTime(boolQuery, callStartTime, callEndTime);
        }
    }

    /**
     * 质检状态查询条件
     * @param boolQuery -
     * @param proStatus -
     */
    public void proStatusFormat(BoolQueryBuilder boolQuery, int proStatus) {
        if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0) {//已质检
            boolQuery.must(
                    QueryBuilders.boolQuery()
                            .should(
                                    QueryBuilders.nestedQuery(
                                            "workScores",
                                            QueryBuilders.matchQuery("workScores.proStatus", BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0),
                                            ScoreMode.None
                                    )
                            )
                            .should(
                                    QueryBuilders.nestedQuery(
                                            "workScores",
                                            QueryBuilders.matchQuery("workScores.proStatus", BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_IN_VALID_7),
                                            ScoreMode.None
                                    )
                            )
                            .should(
                                    QueryBuilders.nestedQuery(
                                            "workScores",
                                            QueryBuilders.matchQuery("workScores.proStatus", BaseEntity.BIG_WORK_PROSTATUS_READ_YES_10),
                                            ScoreMode.None
                                    )
                            )
                            .should(
                                    QueryBuilders.nestedQuery(
                                            "workScores",
                                            QueryBuilders.matchQuery("workScores.proStatus", BaseEntity.BIG_WORK_PROSTATUS_READ_YES_IN_VALID_17),
                                            ScoreMode.None
                                    )
                            )
            );
        } else if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20) {//已申诉
            boolQuery.must(
                    QueryBuilders.boolQuery()
                            .should(
                                    QueryBuilders.nestedQuery(
                                            "workScores",
                                            QueryBuilders.matchQuery("workScores.proStatus", BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20),
                                            ScoreMode.None
                                    )
                            )
                            .should(
                                    QueryBuilders.nestedQuery(
                                            "workScores",
                                            QueryBuilders.matchQuery("workScores.proStatus", BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_IN_VALID_27),
                                            ScoreMode.None
                                    )
                            )
            );
        } else if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30) {//复检完成
            boolQuery.must(
                    QueryBuilders.boolQuery()
                            .should(
                                    QueryBuilders.nestedQuery(
                                            "workScores",
                                            QueryBuilders.matchQuery("workScores.proStatus", BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30),
                                            ScoreMode.None
                                    )
                            )
                            .should(
                                    QueryBuilders.nestedQuery(
                                            "workScores",
                                            QueryBuilders.matchQuery("workScores.proStatus", BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_IN_VALID_37),
                                            ScoreMode.None
                                    )
                            )
            );
        }
    }

    /**
     * 查询任务是否过期
     * @param logTxt -
     * @param work -
     * @return -
     */
    public String taskIs(String logTxt, BusWork work) {
        Session session = SecurityUtils.getSubject().getSession();
        int userIdentity = (Integer) session.getAttribute("userIdentity");
        String daysRemaining;
        if (BaseEntity.USERIDENTITY_ZJ == userIdentity) {//质检
            //申诉过期天数
            int appealInvalid = Integer.parseInt(configMapper.selectByPrimaryKey(Constants.APPEAL_MAX_DAY).getValue());
            //复检过期天数
            int recheckInvalid = Integer.parseInt(configMapper.selectByPrimaryKey(Constants.RECHECK_MAX_DAY).getValue()) + appealInvalid;
            //复检过期日期
            Date recheckInvalidDate = DateFormatUtil.addNDay(work.getStoptime(), recheckInvalid);
            logger.info(logTxt + "复检过期时间" + DateFormatUtil.dateToString(recheckInvalidDate, DateFormatUtil.yyyy_MM_dd_HH_mm_ss));
            daysRemaining = DateFormatUtil.intervalDay(new Date(), recheckInvalidDate) + "";
            logger.info(logTxt + "复检过期剩余天数" + daysRemaining);
        } else if (BaseEntity.USERIDENTITY_ZX == userIdentity) {//坐席
            //申诉过期天数
            int appealInvalid = Integer.parseInt(configMapper.selectByPrimaryKey(Constants.APPEAL_MAX_DAY).getValue());
            //申诉过期日期
            Date appealInvalidDate = DateFormatUtil.addNDay(work.getStoptime(), appealInvalid);
            logger.info(logTxt + "申诉过期日期" + DateFormatUtil.dateToString(appealInvalidDate, DateFormatUtil.yyyy_MM_dd_HH_mm_ss));
            daysRemaining = DateFormatUtil.intervalDay(new Date(), appealInvalidDate) + "";
            logger.info(logTxt + "申诉过期剩余天数" + daysRemaining);
        } else {
            daysRemaining = "-";
        }
        return daysRemaining;
    }

    public void formatShouldQ(String cols, BoolQueryBuilder queryBuilder, String colStr) {
        if (!Strings.isNullOrEmpty(cols)) {
            BoolQueryBuilder shuldQ = new BoolQueryBuilder();
            for (String col : cols.split(",")) {
                shuldQ.should(QueryBuilders.matchQuery(colStr, col));
            }
            queryBuilder.must(shuldQ);
        }
    }

    /**
     * 转写正常语音
     * @return -
     */
    public List<Integer> audioSttYesList() {
        List<Integer> proStatusList = new ArrayList<>();
        proStatusList.add(BaseEntity.AUDIO_PROSTATUS_STT_YES);
        proStatusList.add(BaseEntity.AUDIO_PROSTATUS_NLP_NULL);
        proStatusList.add(BaseEntity.AUDIO_PROSTATUS_NLP_YES);
        proStatusList.add(BaseEntity.AUDIO_PROSTATUS_NLP_NO);
        return proStatusList;
    }

    /**
     * 质检状态 - all
     * @param proStatus -
     * @return -
     */
    public List<Integer> proStatusList(int proStatus) {
        List<Integer> proStatusList = new ArrayList<>();
        if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0) {//已质检
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0);
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_IN_VALID_7);
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_READ_YES_10);
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_READ_YES_IN_VALID_17);
        } else if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20) {//已申诉
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20);
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_IN_VALID_27);
        } else if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30) {//复检完成
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30);
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_IN_VALID_37);
        }
        return proStatusList;
    }

    /**
     * 质检状态过期
     * @param proStatus -
     * @return -
     */
    public List<Integer> proStatusInValidList(int proStatus) {
        List<Integer> proStatusList = new ArrayList<>();
        if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0) {//已质检
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_IN_VALID_7);
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_READ_YES_IN_VALID_17);
        } else if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20) {//已申诉
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_IN_VALID_27);
        } else if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30) {//复检完成
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_IN_VALID_37);
        }
        return proStatusList;
    }

    /**
     * 质检状态不过期
     * @param proStatus -
     * @return -
     */
    public List<Integer> proStatusValidList(int proStatus) {
        List<Integer> proStatusList = new ArrayList<>();
        if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0) {//已质检
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0);
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_READ_YES_10);
        } else if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20) {//已申诉
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20);
        } else if (proStatus == BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30) {//复检完成
            proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30);
        }
        return proStatusList;
    }

    /**
     * 不过期
     * @return -
     */
    public List<Integer> inValidList() {
        List<Integer> proStatusList = new ArrayList<>();
        proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_0);
        proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_READ_YES_10);
        proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_20);
        proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_30);
        return proStatusList;
    }

    /**
     * 过期
     * @return -
     */
    public List<Integer> validList() {
        List<Integer> proStatusList = new ArrayList<>();
        proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_QUALITY_YES_IN_VALID_7);
        proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_READ_YES_IN_VALID_17);
        proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_APPEAL_YES_IN_VALID_27);
        proStatusList.add(BaseEntity.BIG_WORK_PROSTATUS_RECHECK_YES_IN_VALID_37);
        return proStatusList;
    }

    /**
     * 规则分数计算
     *
     * 计算申诉成功后模型规则的分数	　	　	                  当前规则分值	                                     语音分值	             任务*人分值
     *           按照任务计算分数	非致命性	分数上限不为空时 	单次分值*命中量 和任务上限比较，绝对值哪个小，取哪个	   规则分值总和	        规则分值总和+任务总分
     *                                  分数上限为空时	    单次分值*命中量
     *                          致命性	分数上限不为空时	该值 (分数上限)
     *                                  分数上限为空时	    -模型总分      	                               -任务总分	            0
     *           按照音频计算分数	非致命性	分数上限不为空时 	单次分值*命中量 和任务上限比较，绝对值哪个小，取哪个	   规则分值总和+任务总分	语音总分/语音量
     *                                  分数上限为空时	    单次分值*命中量
     *                          致命性	分数上限不为空时	该值 (分数上限)
     *                                  分数上限为空时	    -模型总分     	                               0
     * @param scorePerTime - 单次扣分值    -1101
     * @param fateful - 致命性   1
     * @param ruleTimes - 规则命中量     0
     * @param max - 分数上限    null
     * @param fullScore - 满分   1101
     * @return - 计算好的分数
     */
    public Integer formatModelRuleScoure(Integer scorePerTime, Integer fateful, Integer ruleTimes, Integer max, int fullScore) {
        //所有匹配总分数 = 单次分值 * 规则命中量
        int sum = scorePerTime*ruleTimes;
        if (fateful != null && BaseEntity.FATEFUL_ART == fateful) {//致命性规则
            if (ruleTimes == 0) {
                return 0;
            } else if (max == null) {
                return -fullScore;
            } else if (max == 0) {
                return 0;
            } else {
                return max;
            }
        } else {//非致命性规则
            if (max == null) {
                return sum;
            } else {
                return Math.abs(max) - Math.abs(sum) >= 0 ? sum : max;
            }
        }
    }

    /**
     *
     *      * 计算申诉成功后模型规则的分数	　	　	                                    语音分值
     *      *           按照任务计算分数	非致命性	分数上限不为空时 		          规则分值总和
     *      *                                   分数上限为空时
     *      *                           致命性	分数上限不为空时
     *      *                                   分数上限为空时	      	           -任务总分
     *      *           按照音频计算分数	非致命性	分数上限不为空时 	              规则分值总和+任务总分
     *      *                                   分数上限为空时
     *      *                           致命性   分数上限不为空时
     *      *                                   分数上限为空时                    0
     *
     * 计算任务中语音分值
     * @param modelRules - 任务的模型规则列表
     * @param scoreflag - 算分方式
     * @param fullScore - 满分
     * @return -
     */
    public Integer formWorkScore(List<ModelRules> modelRules, List<RuleInfos> ruleInfos, int scoreflag, int fullScore) {
        Integer sum = 0;
        boolean fatefulAndMaxScore = false;//致命性 和  分数上限
        for (ModelRules modelRule : modelRules) {
            sum += modelRule.getRuleScore();
            //查看规则命中量是否为0，为0则不参加下列判断中
            boolean ruleTimes = true;//名重量是否不为0
            for (RuleInfos rule : ruleInfos) {
                if (modelRule.getRuleId().toString().equals(rule.getRuleId().toString())) {
                    if (rule.getRuleTimes() <= 0) {
                        ruleTimes = false;
                    }
                }
            }
            if (ruleTimes) {
                BusModelRuleExample example = new BusModelRuleExample();
                example.createCriteria().andRuleidEqualTo(modelRule.getRuleId()).andModelidEqualTo(modelRule.getModelId());
                List<BusModelRule> busModelRules = busModelRuleMapper.selectByExample(example);
                if (busModelRules == null) {
                    continue;
                }
                BusModelRule busModelRule = busModelRules.get(0);
                if (busModelRule.getMaxscore() == null && busModelRule.getFateful() == BaseEntity.FATEFUL_ART) {
                    fatefulAndMaxScore = true;
                }
            }
        }
        if (scoreflag == BaseEntity.SCORE_FLAG_TASK) {//任务
            return fatefulAndMaxScore ? -fullScore : sum;
        } else if (scoreflag == BaseEntity.SCORE_FLAG_AUDIO) {//音频
            int all = fullScore + sum <= 0 ? 0 : (fullScore + sum);
            return fatefulAndMaxScore ? 0 : all;
        }
        return 0;
    }

    public String changeState(Integer proStatus) {
        Map<Integer, String> map = new HashMap<>();
        map.put(0, "质检完成");
        map.put(7, "质检完成已过期");
        map.put(10, "质检完成已读");
        map.put(17, "质检完成已读已过期");
        map.put(20, "已申诉");
        map.put(27, "已申诉过期");
        map.put(30, "复检完成");
        map.put(37, "复检完成过期");
        map.put(40, "复检完成已读");
        return map.get(proStatus);
    }

    /**
     * 挂机方
     * @param proStatus -
     * @return -
     */
    public String changeOnHook(String proStatus) {
        return SystemStatic.ONHOOK_MAP.get(proStatus);
    }

    /**
     * 客户星级
     * @param proStatus -
     * @return -
     */
    public String changeCustomerLevel(String proStatus) {
        return SystemStatic.CUSTOMERLEVEL_MAP.get(proStatus);
    }

    /**
     * 满意度
     * @param proStatus -
     * @return -
     */
    public String changeSatisfaction(String proStatus) {
        return SystemStatic.SATISFACTION_MAP.get(proStatus);
    }

    /**
     * 质检任务状态
     * @param proStatus =
     * @return -
     */
    public String changeTaskStatus(int proStatus) {
        Map<Integer, String> map = new HashMap<>();
        map.put(0, "未启动");
        map.put(1, "检测中");
        map.put(2, "检测中");
        map.put(3, "检测完成");
        map.put(4, "已停止");
        return map.get(proStatus);
    }

    /**
     * 致命性
     * @param fateful =
     * @return -
     */
    public String changeRuleFateFul(int fateful) {
        Map<Integer, String> map = new HashMap<>();
        map.put(-1, "");
        map.put(0, "否");
        map.put(1, "是");
        return map.get(fateful);
    }

    /**
     * 审批任务状态
     * @param proStatus =
     * @return -
     */
    public String changeExportTaskStatus(int proStatus) {
        Map<Integer, String> map = new HashMap<>();
        map.put(0, "未审批");
        map.put(1, "审批中");
        map.put(2, "审批通过");
        map.put(3, "审批不通过");
        return map.get(proStatus);
    }

    /**
     * 审批任务状态
     * @param proStatus =
     * @return -
     */
    public String changeExportFileStatus(int proStatus) {
        Map<Integer, String> map = new HashMap<>();
        map.put(0, "排队中");
        map.put(1, "处理中");
        map.put(2, "处理完成");
        return map.get(proStatus);
    }

}
